#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>

#define NUM 1024

#define NONE_FLUSH 0x0
#define LINE_FLUSH 0x1
#define FULL_FLUSH 0x2

typedef struct _MyFILE
{
    int _fileno;
    char _buffer[NUM];
    int _end;
    int _flags;//fflush method
}MyFILE;

MyFILE *my_fopen(const char* filename,const char*method)
{
    assert(filename);
    assert(method);

    int flags = O_RDONLY;

    if(strcmp(method,"r") == 0)
    {
    }
    else if(strcmp(method,"r+") == 0)
    {}
    else if(strcmp(method,"w") == 0)
    {
        flags = O_WRONLY | O_CREAT |O_TRUNC;
    }
    else if(strcmp(method,"w+") == 0)
    {}
    else if(strcmp(method,"a") == 0)
    {
        flags = O_WRONLY | O_CREAT |O_APPEND;
    }
    else if(strcmp(method,"a+") == 0)
    {}

    int fileno = open(filename,flags,0666);
    if(fileno < 0)
    {
        return NULL;
    }

    MyFILE *fp = (MyFILE*)malloc(sizeof(MyFILE));
    if(fp  == NULL ) return fp;
    memset(fp,0,sizeof(MyFILE));

    fp->_fileno = fileno;
    fp->_flags |= LINE_FLUSH;
    fp->_end = 0;
    return fp;
}
void my_fflush(MyFILE* fp)
{   
    assert(fp);
    if(fp->_end > 0)
    {
        write(fp->_fileno,fp->_buffer,fp->_end);
        fp->_end =0;
        syncfs(fp->_fileno);
    }

}

void my_fwrite(MyFILE* fp,const char* start,int len)
{
    assert(fp);
    assert(start);
    assert(len>0);

    // abcde->追加
    strncpy(fp->_buffer+fp->_end,start,len);//将数据写入缓冲区
    fp->_end += len;
    
    if(fp->_flags & NONE_FLUSH){}
    if(fp->_flags & LINE_FLUSH)
    {
        if(fp->_end > 0 && fp->_buffer[fp->_end-1] == '\n') 
        {
            write(fp->_fileno,fp->_buffer,fp->_end);
            fp->_end = 0;
            syncfs(fp->_fileno);
        }
    }
    if(fp->_flags & FULL_FLUSH){}

}

void my_fclose(MyFILE* fp)
{
    my_fflush(fp);
    close(fp->_fileno);
    free(fp);
}

int main()
{
    MyFILE * fp = my_fopen("log.txt","w");
    if(fp == NULL)
    {
        printf("my_fopen error\n");
        return 1;
    }
    // const char *msg = "hello my_file 11111111\n";
    // my_fwrite(fp,msg,strlen(msg));
    
    // printf("hello my_file 11111111消息立即刷新\n");
    // sleep(3);
    

    // const char *mssg = "hello 222222222";
    // my_fwrite(fp,mssg,strlen(mssg));
    // sleep(3);
    // printf("写入了一个不满足条件的字符串hello 222222222\n");

    // const char *msssg = "hello 33333333";
    // my_fwrite(fp,msssg,strlen(msssg));
    // sleep(3);
    // printf("写入了一个不满足条件的字符串hello 33333333\n");

    // const char *mssssg = "end\n";
    // my_fwrite(fp,mssssg,strlen(mssssg));
    // printf("写了一个满足条件的字符串end\n");
    // sleep(3);


    // const char *msssssg = "aaaaaaa";
    // my_fwrite(fp,msssssg,strlen(msssssg));
    // printf("写了一个满足条件的字符串aaaaaaa\n");
    // sleep(1);
    // my_fflush(fp);
    // sleep(3);

    const char* msg = "aaaaa";
    my_fwrite(fp,msg,strlen(msg));
    printf("写入了一个不满足刷新条件的字符串\n");
    fork();
    //模拟进程提出
    my_fclose(fp);
    return 0;
}